]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
Special-handle Empathy to have multiple sources and to queue notifications
authorMarina Zhurakhinskaya <marinaz@redhat.com>
Mon, 22 Feb 2010 22:26:00 +0000 (17:26 -0500)
committerMarina Zhurakhinskaya <marinaz@redhat.com>
Mon, 22 Feb 2010 22:27:23 +0000 (17:27 -0500)
We are planning to add Empathy-specific features in the message tray, but in the
meantime we handle Empathy notifications received through the notification daemon
so that their behavior is closer to the eventual design, which is how it was before
we started associating applications with a single source and enabled notification
replacement.

js/ui/messageTray.js
js/ui/notificationDaemon.js

index a1f6509af38fdf8951f59b9fbc5ad9146b3282b8..2b11387e33563242052226aadae9ed86b8f60556 100644 (file)
@@ -328,6 +328,7 @@ Source.prototype = {
         this.text = null;
         if (createIcon)
             this.createIcon = createIcon;
+        this.handleReplacing = true;
     },
 
     // This can be overridden by a subclass, or by the createIcon
@@ -520,7 +521,7 @@ MessageTray.prototype = {
     },
 
     _onNotify: function(source, notification) {
-        if (this._getNotification(notification.id, source) == null) {
+        if (!notification.source.handleReplacing || this._getNotification(notification.id, source) == null) {
             notification.connect('destroy',
                                  Lang.bind(this, this.removeNotification));
             this._notificationQueue.push(notification);
index deb735226f5226846428d349f4b366c63c67a5e9..7f5dfcf7e32b99967db366044c700c367097a1b2 100644 (file)
@@ -10,6 +10,8 @@ const Main = imports.ui.main;
 const MessageTray = imports.ui.messageTray;
 const Params = imports.misc.params;
 
+const EMPATHY = 'Empathy';
+
 let nextNotificationId = 1;
 
 // Should really be defined in dbus.js
@@ -131,13 +133,46 @@ NotificationDaemon.prototype = {
 
     Notify: function(appName, replacesId, icon, summary, body,
                      actions, hints, timeout) {
-        let source = Main.messageTray.getSource(this._sourceId(appName));
-        let id = null;
+        let notification, id;
+        // We associate each application with a source and set the source id to be based on
+        // the appName. We support application updates by creating a new Notification object
+        // only if replacesId was not specified or if we no longer have the notification with
+        // the specified replacesId.
+        //
+        // We are planning to add Empathy-specific features in the message tray, but in the
+        // meantime we handle Empathy notifications received through the notification daemon
+        // differently from other notifications.
+        // 1) We display different people sending messages as different sources. So we use
+        //    notification id instead of the appName when creating id for the source.
+        // 2) We queue notification with different messages to show them one after another,
+        //    rather than replace the notification on the spot. So we create a new Notification
+        //    object each time, disregarding the fact that we might already have another
+        //    notification with the same replacesId.
+        // Empathy uses replacesId for all the notifications from the same window until the
+        // notification with that id is dismissed. Notifications from different people in
+        // different tabs have the same replacesId. So while being closer to the eventual design,
+        // our special-handling of Empathy notifications is somewhat buggy. The user might end up
+        // with multiple icons for the same person if the user dismisses the window for that person
+        // (which doesn't result in removing the icon) or the user might not get the icon for
+        // the person after a new notification in one of the tabs of the chat window for which
+        // another person's icon is already displayed.
+
+        let isEmpathy = appName == EMPATHY;
+        if (replacesId != 0) {
+            id = replacesId;
+            if (!isEmpathy)
+                notification = this._currentNotifications[id];
+        } else {
+            id = nextNotificationId++;
+        }
+
+        let sourceId = this._sourceId(isEmpathy ? id : appName);
+        let source = Main.messageTray.getSource(sourceId);
 
         // Source may be null if we have never received a notification from
         // this app or if all notifications from this app have been acknowledged.
         if (source == null) {
-            source = new Source(this._sourceId(appName), icon, hints);
+            source = new Source(sourceId, icon, hints);
             Main.messageTray.add(source);
 
             source.connect('clicked', Lang.bind(this,
@@ -166,15 +201,14 @@ NotificationDaemon.prototype = {
             }
         }
 
-        let notification;
-        if (replacesId != 0) {
-            id = replacesId;
-            notification = this._currentNotifications[id];
-        }
-
         if (notification == null) {
-            id = nextNotificationId++;
             notification = new MessageTray.Notification(id, source, summary, body, true);
+            // This will result in us keeping only the latest Empathy notification with the given
+            // id in this._currentNotifications, which will only affect not being able to close all
+            // the Empathy notifications with a given id in CloseNotification(). Since this not a
+            // a likely scenario and this special-casing of Empathy in the notification daemon is
+            // temporary, it doesn't seem worthwhile to change this._currentNotifications to
+            // {id, [array of notifications]} just for that case.
             this._currentNotifications[id] = notification;
             notification.connect('dismissed', Lang.bind(this,
                 function(n) {
@@ -313,6 +347,9 @@ Source.prototype = {
         this.app = app;
         if (this._openAppRequested)
             this.openApp();
+
+        if (app.get_name() == EMPATHY)
+            this.handleReplacing = false;
     },
 
     openApp: function() {